#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/wait.h>

#define MSG_SIZE 512

struct msg {
    long msg_type;
    char msg_text[MSG_SIZE];
};

int main(void) {
    int qid;
    pid_t pid;
    struct msg send_msg, recv_msg;

    // 创建消息队列
    if ((qid = msgget(IPC_PRIVATE, IPC_CREAT | 0666)) < 0) {
        perror("msgget");
        exit(1);
    }

    printf("Message queue created with ID: %d\n", qid);

    // 创建两个子进程
    pid = fork();
    if (pid < 0) {
        perror("fork");
        exit(1);
    }

    if (pid == 0) {
        // 子进程 P1
        printf("Child P1 (PID: %d) is sending a message...\n", getpid());
        send_msg.msg_type = 1; // 消息类型为 1

            memset(send_msg.msg_text, 'A', MSG_SIZE - 1); // 填充 511 字节的 'A'
            send_msg.msg_text[MSG_SIZE - 1] = '\0';       // 确保字符串以 '\0' 结尾


        if (msgsnd(qid, &send_msg, sizeof(send_msg.msg_text), 0) < 0) {
            perror("msgsnd");
            exit(1);
        }

        printf("Child P1 sent message: %s\n", send_msg.msg_text);

        // 等待接收消息
        if (msgrcv(qid, &recv_msg, sizeof(recv_msg.msg_text), 2, 0) < 0) {
            perror("msgrcv");
            exit(1);
        }

        printf("Child P1 received message: %s\n", recv_msg.msg_text);

        exit(0);
    } else {
        // 父进程继续创建第二个子进程
        pid = fork();
        if (pid < 0) {
            perror("fork");
            exit(1);
        }

        if (pid == 0) {
            // 子进程 P2
            printf("Child P2 (PID: %d) is sending a message...\n", getpid());
            send_msg.msg_type = 2; // 消息类型为 2
            
                memset(send_msg.msg_text, 'B', MSG_SIZE - 1); // 填充 511 字节的 'B'
            send_msg.msg_text[MSG_SIZE - 1] = '\0';       // 确保字符串以 '\0' 结尾


            if (msgsnd(qid, &send_msg, sizeof(send_msg.msg_text), 0) < 0) {
                perror("msgsnd");
                exit(1);
            }

            printf("Child P2 sent message: %s\n", send_msg.msg_text);

            // 等待接收消息
            if (msgrcv(qid, &recv_msg, sizeof(recv_msg.msg_text), 1, 0) < 0) {
                perror("msgrcv");
                exit(1);
            }

            printf("Child P2 received message: %s\n", recv_msg.msg_text);

            exit(0);
        } else {
            // 父进程等待两个子进程结束
            wait(NULL);
            wait(NULL);

            // 删除消息队列
            if (msgctl(qid, IPC_RMID, NULL) < 0) {
                perror("msgctl");
                exit(1);
            }

            printf("Message queue removed.\n");
        }
    }

    return 0;
}